#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
#include<string>
#include<list>
#include<algorithm>
using namespace std;

void test_string1()
{
	string s1;
	string s2("hello world");
	string s3(s2);

	string s4(s2, 3, 5);
	string s5(s2, 3);
	string s6(s2, 3, 30);
	string s7("hello world", 5);
	string s8(10, 'x');

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;
	cout << s7 << endl;
	cout << s8 << endl;

	cin >> s1;
	cout << s1 << endl;
}

void push_back(const string& s)
{

}

void test_string2()
{
	string s2 = "hello world";
	const string& s3 = "hello world";

	string s1("hello world");
	push_back(s1);

	push_back("hello world");
}

//class string
//{
//public:
//	char& operator[](size_t i)
//	{
//		assert(i < _size);
//		return _str[i];
//	}
//private:
//	char* _str;
//	size_t _size;
//	size_t _capacity;
//};

void test_string3()
{
	string s1("hello world");
	s1[0] = 'x';

	cout << s1.size() << endl;
	cout << s1.length() << endl;

	for (size_t i = 0; i < s1.size(); i++)
	{
		s1[i]++;
	}
	cout << endl;
	s1[0] = 'x';

	//s1[20];

	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;

	const string s2("hello world");
	//s2[9] = 'c';
}

void test_string4()
{
	string s1("hello world");

	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;

	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		*it1 += 3;

		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

	cout << s1 << endl;
	for (auto& e : s1)
	{
		e++;
		cout << e << " ";
	}
	cout << endl;
	cout << s1 << endl;

	list<int> lt1;
	lt1.push_back(1);
	lt1.push_back(2);
	lt1.push_back(3);

	list<int>::iterator it = lt1.begin();
	while (it != lt1.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

	list<double> lt2;
}

//template<class T>
//struct ListNode
//{
//	ListNode<T>* _next;
//	ListNode<T>* )prev;
//	T _data;
//};
//
//template<class T>
//class list
//{
//private:
//	ListNode<T>* _head;
//};

void test_string5()
{
	const string s1("hello world");
	string::const_iterator it1 = s1.begin();
	//auto it1 = s1.begin();
	while (it1 != s1.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

	string::const_reverse_iterator cit1 = s1.rbegin();
	//auto cit1 = s1.begin();
	while (cit1 != s1.rend())
	{
		//*cit1 += 3;

		cout << *cit1 << " ";
		++cit1;
	}
	cout << endl;

	string s2("hello world");
	string::reverse_iterator it2 = s2.rbegin();
	//auto it2 = s2.rbegin();
	while (it2 != s2.rend())
	{
		*it2 += 3;

		cout << *it2 << " ";
		++it2;
	}
	cout << endl;
}

void test_string6()
{
	string s1("hello world");
	cout << s1 << endl;

	//sort(s1.begin(), s1.end());
	//cout << s1 << endl;
	//sort(++s1.begin(), --s1.end());
	//cout << s1 << endl;

	sort(s1.begin(), s1.begin() + 5);
	cout << s1 << endl;
}

void test_string7()
{
	string s1("hello world");
	cout << s1 << endl;

	s1.push_back('x');
	cout << s1 << endl;

	s1.append(" yyyyy!!");
	cout << s1 << endl;

	string s2("1111111");

	s1 += 'y';
	s1 += "zzzzzzzzz";
	s1 += s2;
	cout << s1 << endl;
}

void test_string8()
{
	string s1("hello world");
	cout << s1 << endl;

	s1.assign("111111");
	cout << s1 << endl;

	string s2("hello world");
	s2.insert(0, "xxxx");
	cout << s2 << endl;

	char ch = 'y';
	cin >> ch;
	s2.insert(0, 1, ch);
	cout << s2 << endl;

	s2.insert(s2.begin(), 'y');
	cout << s2 << endl;

	s2.insert(s2.begin(), s1.begin(), s1.end());
	cout << s2 << endl;
}

void test_string9()
{
	string s1("hello world");
	cout << s1 << endl;

	s1.erase(0, 1);
	cout << s1 << endl;

	s1.erase(5, 100);
	cout << s1 << endl;

	string s2("hello world");
	s2.replace(5, 1, "%20");
	cout << s2 << endl;

	string s3("hello world hello bit");
	for (size_t i = 0; i < s3.size();)
	{
		if (s3[i] == ' ')
		{
			s3.replace(i, 1, "%20");
			i += 3;
		}
		else
		{
			i++;
		}
	}
	cout << s3 << endl;

	string s4("hello world hello bit");
	string s5;
	for (auto ch : s4)
	{
		if (ch != ' ')
		{
			s5 += ch;
		}
		else
		{
			s5 += "%20";
		}
	}
	cout << s5 << endl;
}

void TestPushBack()
{
	string s;
	//s.reserve(200);
	//s[100] = 'x';

	size_t sz = s.capacity();
	cout << "capacity changed: " << sz << '\n';

	cout << "making s grow:\n";
	for (int i = 0; i < 200; ++i)
	{
		s.push_back('c');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

void test_string10()
{
	//string s1("hello world hello bit");
	////string s1;
	//cout << s1.size() << endl;
	//cout << s1.capacity() << endl;
	//cout << s1.max_size() << endl;
	//

	TestPushBack();

	string s1("111111111111");
	string s2("1111111111111111111111111111111111111111111111111111");

	cout << s2.capacity() << endl;

	s1.reserve(100);
	cout << s1.capacity() << endl;

	s1.reserve(20);
	cout << s1.capacity() << endl;
}

void test_string11()
{
	string s1;
	s1.resize(5);
	s1[4] = '3';
	s1[3] = '4';
	s1[2] = '5';
	s1[1] = '6';
	s1[0] = '7';
	cout << s1 << endl;

	string s2("hello world");
	s2.resize(20, 'x');
	cout << s2 << endl;

	s2.resize(5);
	cout << s2 << endl;

	try
	{
		//s2[10];
		//s2.at(10);
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}

	string file("test.cpp");
	FILE* fout = fopen(file.c_str(), "r");
	char ch = fgetc(fout);
	while (ch != EOF)
	{
		cout << ch;
		ch = fgetc(fout);
	}
}

void test_string12()
{
	string file("string.cpp.zip");
	size_t pos = file.rfind('.');
	string suffix = file.substr(pos);

	cout << suffix << endl;
}

int main()
{
	test_string12();
	//TestPushBack();
	return 0;
}